首先先看一下下面的程式:
for (var i = 0; i < 10; i++) {
setTimeout(function () {
console.log('這執行第' + i + '次');
}, 10);
}
console.log(i);
這段重要的事情是,setTimeout 會延遲執行現在的 i 是多少,並且在最外面會印出執行完 for迴圈之後的 i 是多少。
上一篇文章也有講到,因為這邊是用 var 進行變數的宣告,所以最外面的 console.log(i);
是有辦法抓的到 i 的值。
現在又有一個問題來了,因為 setTimeout 是非同步執行的,現在的結果會是我們預期的 0~9,還是都是一樣的 10 呢?
看到了結果,第一個呈現的是10,很明顯,因為 setTimeout 是非同步執行的,所以會在所有的code都執行玩了以後,才執行。
但為什麼,預期的 0~9,會是一樣的 10 呢?
主要原因就是因為 i 是全域變數,而 setTimeout 是非同步執行的,當全部的code都執行完以後,才進入事件佇列中進行取值的動作,這個時候取到的不是for迴圈裡面的 i ,而是全域變數已經被 + 到 10 的 i,所以一直都是顯示10。
而且就算我們把 setTimeout 的時間改成 0,結果也還是一樣的喔!
那麼如果現在是let進行宣告變數的話,就會改善這個問題喔!
for (let i = 0; i < 10; i++) {
setTimeout(function () {
console.log('這執行第' + i + '次');
}, 0);
}
// console.log(i);
只是要記得把最後面的 console.log(i);
給拿掉,因為在Block之外的話就取不到裡面的 i 會報錯。
var person = {
name: '小明',
money: 500
};
person.name = '杰倫';
以前我們宣告物件的方式都是用這樣的方法進行宣告,並利用 person.name = '杰倫';
的方式進行物件屬性值的調整。
那麼現在如果換成 const 的話,也是完全沒有問題的喔~
但上一篇文章不是說~const宣告的變數是不能做更動的嗎?
沒錯喔,但是這裡的變數是物件,物件傳參考的特性,所以是不能改變物件參考的位置,但針對物件中的屬性對應的值進行修改是沒有問題的喔~!
所以直接改變 person 這個物件的參考位置,也就是重新給予另一個物件的話,就不行喔!
那再來我們把宣告變數改成 var ~
並且freeze該物件~
所以理所當然我們沒辦法改動裡面的屬性的值~
var person = {
name: '小明',
money: 500
};
person.name = '杰倫';
Object.freeze(person);
person.money = 1000;
這個時候,我再把這個物件改變成其他物件(變換物件傳參考的指向)~
var person = {
name: '小明',
money: 500
};
person.name = '杰倫';
Object.freeze(person);
person.money = 1000;
person = {};
你就會發現,person的位置被改掉了~
如同之前介紹的,freeze針對的是整個物件的所有屬性,但不包含物件的參考指向。
所以要解決這個問題,只要使用const進行變數的宣告就可以!
你看,這樣的話,他就報錯提醒你不可以這樣重新改變person這個變數對於物件的指向!!
好~這篇文章就介紹到這邊,如果沒有問題的話就繼續往下巴~汪汪!